# coding=utf8
import uuid

from flask import Blueprint, g, request, jsonify, render_template, session, redirect, url_for, make_response
from sqlalchemy.exc import InvalidRequestError

import datetime
from database import db
from models import Manager, Team, Member, CheckPoint, TeamSignLog
from saltedpwd import Salted
from hashlib import sha256, sha1
import logging
from StringIO import StringIO


bp = Blueprint('admin', __name__, template_folder='templates/admin', url_prefix='/admin')


from functools import wraps

def _logined(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if session.get('manager_id') and Manager.byId(int(session.get('manager_id'))):
            return func(*args, **kwargs)
        else:
            return redirect(url_for('admin.show_login'))
    return wrapper


@bp.route("")
@_logined
def main():
    return render_template("admin/index.html")

@bp.route("/login")
def show_login():
    return render_template("admin/login.html")


@bp.route("/logout")
def do_logout():
    session ['manager_id'] = ''
    return redirect(url_for('admin.main'))


@bp.route("/login", methods=["POST"])
def do_login():
    email = request.form.get('email')
    password = request.form.get('password')
    salted = Salted(sha256)
    manager = Manager.query.filter(Manager.email == email).first()
    if not manager:
        return jsonify(code=404, error=u"用户名密码错误")
    if not salted.verify_password(password, manager.password):
        return jsonify(code=401, error=u"用户名密码错误")
    session['manager_id'] = manager.id
    return jsonify(code=200)


@bp.route("/password", methods=["POST"])
@_logined
def reset_password():
    pwd = request.form.get('pwd')
    new_pwd = request.form.get('new_pwd')
    re_pwd = request.form.get('re_pwd')
    manager = Manager.byId(int(session.get('manager_id')))
    salted = Salted(sha256)
    if new_pwd!=re_pwd:
        return jsonify(code=500, error=u"两次密码输入不一致")

    if new_pwd == pwd:
        return jsonify(code=500, error=u"新密码和当前密码一样")

    logging.error("pwd:%s", pwd)
    if not salted.verify_password(pwd, manager.password):
        return jsonify(code=403, error=u"当前密码不正确")

    manager.password = salted.gen_password(new_pwd)
    db.commit()
    return jsonify(code=200)


@bp.route("/teams")
@_logined
def manage_teams():
    STATUS = {
        0: u"刚创建初始状态",
        1: u"登录过未填信息",
        2: u"自己填过信息了"
    }
    pid = int(request.args.get('p', '1'))
    psize = 20
    name = request.args.get('name', '')
    item_count = Team.query.filter(Team.teamName.like(name + '%')).count()
    teams = Team.query.filter(Team.teamName.like(name + '%')).order_by(Team.id.desc())[(pid - 1)*psize: pid*psize]
    teams_data = []
    for team in teams:
        members = Member.query.filter(Member.teamId == team.id).all()
        teams_data.append({"id":team.id, "name": team.teamName, "members": members})
    page_count = item_count / psize
    if item_count % psize != 0:
        page_count+=1
    prev_id = pid if pid < 2 else pid -1
    next_id = pid if pid > page_count - 2 else pid + 1

    return render_template("admin/manage_registed.html", **locals())


@bp.route("/team/<team_id>/member/<member_id>/mobile", methods=["POST"])
@_logined
def change_mobile(team_id, member_id):
    mobile = request.form.get('mobile', '')
    if not mobile or len(mobile)!=11:
        return jsonify(code=500, error=u"错误的手机号码")
    team = Team.byId(int(team_id))
    if not team:
        return jsonify(code=404, error=u"参赛队伍不存在")
    member = Member.byId(int(member_id))
    if not member:
        return jsonify(code=404, error=u"参赛人员不存在")

    from www.sms_service import getSmsService, template_id
    smsService = getSmsService()
    if smsService.send(mobile, template_id, [member.password,]):
        if member.mobile == team.leaderMobile:
            team.leaderMobile = mobile
        member.mobile = mobile
        db.commit()
    return jsonify(code=200)


def _gen_pwd():
    from random import sample
    return "".join(sample('123456789012345678901234567890', 6))


@bp.route("/teams", methods=["POST"])
@_logined
def create_team():
    name = request.form.get('teamName')
    mobiles = request.form.get('mobiles')
    if Team.query.filter(Team.teamName == name.strip()).first():
        return jsonify(code=500, error=u"队名已经被占用")
    mobile_numbers = []
    for mobile in mobiles.split('\n'):
        if len(mobile.strip())!=11:
            return jsonify(code=500, error=u"手机号码 %s 非法" % mobile)
        if mobile.strip()[0]!='1' or mobile.strip()[1] not in ['3', '4', '5','6','7', '8', '9']:
            return jsonify(code=500, error=u"手机号码 %s 非法" % mobile)
        if Member.query.filter(Member.mobile == mobile.strip()).first():
            return jsonify(code=500, error=u"手机号码 %s 已经参赛了" % mobile)
        mobile_numbers.append(mobile.strip())
    if len(mobile_numbers)!=5:
        return jsonify(code=500, error=u"参赛人数不是五人")

    from www.sms_service import getSmsService, template_id
    smsService = getSmsService()


    team = Team(teamName=name, leaderMobile=mobile_numbers[0], status=1)
    db.add(team)
    db.flush()

    members = 0

    for i in range(5):
        try:
            pwd = _gen_pwd()
            member = Member(teamId=team.id, mobile = mobile_numbers[i], password=pwd, weixinId='', status=0)
            sms_rs = smsService.send(mobile_numbers [i], template_id, [pwd, ])
            db.add(member)
            db.flush()
            members += 1 if sms_rs else 0
        except InvalidRequestError as e:
            db.rollback()
            return jsonify(code=500, error=u"电话号码:%s 已经注册过了" % mobile_numbers[i])

    team.status = members
    db.commit()
    return jsonify(code=200)


@bp.route("/teams/dumps")
@_logined
def dump_teams():
    rows = []
    rows.append(u",".join([u"队伍", u"身份", u"姓名", u"电话", u"身份证", u"地址"]))
    for team in Team.query.filter().all():
        for member in Member.query.filter(Member.teamId == team.id).order_by(Member.id.asc()):
            rows.append(u",".join([
                team.teamName,
                u"队长" if team.leaderMobile == member.mobile else u"队员",
                member.realName or u"未填",
                member.mobile,
                member.idNo or u"未填",
                member.address or u"未填"
            ]))
    si = StringIO()
    si.write(u"\r\n".join(rows))
    output = make_response(si.getvalue())
    output.headers ["Content-Disposition"] = "attachment; filename=export.csv"
    output.headers ["Content-type"] = "text/csv"
    return output


def _check_hour(ts):
    dt = datetime.datetime.fromtimestamp(ts)
    return dt.hour
        
@bp.route("/check/dumps")
@_logined
def dumps_data():
    exception_list = []
    #  exception_list.append('')
    #  exception_list.append('')
    doubles = {
        10: [54, 53, 52, 51, 50],
        11: [30, ],
        12: [55, 41, 28],
        13: [29, ],
        14: [21, ],
        15: [34, ]
    }

    rows = []
    rows.append(u",".join([u"队伍", u"合规签到点数", u"双倍点数", u"签到分数", u"拍照分数", u"合计"]))
    for team in Team.query.filter().all():
        teamsignlogs = TeamSignLog.query.filter(TeamSignLog.team_id == team.id).all()
        points = 0
        check_count = 0
        double_count = 0
        for teamsignlog in teamsignlogs:
            checkPoint = CheckPoint.byId(teamsignlog.check_point_id)
            ck_hour = _check_hour(teamsignlog.first_check_ts)
            secs = doubles.get(ck_hour)
            check_count +=1
            points += checkPoint.point
            if secs and teamsignlog.check_point_id in secs:
                double_count += 1
                points += checkPoint.point

        rows.append(u",".join([
            team.teamName,
            u"%d" % check_count,
            u"%s" % double_count,
            u"%d" % points,
            u"",
            u""
        ]))
    si = StringIO()
    si.write(u"\r\n".join(rows))
    output = make_response(si.getvalue())
    output.headers ["Content-Disposition"] = "attachment; filename=export.csv"
    output.headers ["Content-type"] = "text/csv"
    return output


@bp.route("/points", methods=["GET", "POST"])
@_logined
def manage_check_points():
    if request.method == "GET":
        pid = int(request.args.get('p', '1'))
        psize = 5
        name = request.args.get('name', '')

        query = CheckPoint.query.filter(CheckPoint.name.like(name + "%"))

        item_count = query.count()
        points = query.order_by(CheckPoint.id.desc())[(pid - 1)*psize: pid*psize]
        page_count = item_count / psize
        if item_count % psize != 0:
            page_count += 1
        prev_id = pid if pid < 2 else pid - 1
        next_id = pid if pid > page_count - 2 else pid + 1

        return render_template("admin/manage_check_point.html", **locals())
    name = request.form.get('name')
    point = int(request.form.get('point', '0'))
    if not name:
        return jsonify(code=500, info=u"签到点名不能为空")
    if not point:
        return jsonify(code=500, info=u"分值不能为0")
    checkpoint = CheckPoint(name=name, key=uuid.uuid4().hex, point=point)
    db.add(checkpoint)
    db.commit()
    return jsonify(code=200)
    

@bp.route("/points/<cid>/delete", methods=["POST"])
@_logined
def delete_check_point(cid):
    CheckPoint.query.filter(CheckPoint.id == int(cid)).delete()
    db.commit()
    return jsonify(code=200)


    
        

